#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <chrono>

// 共享数据队列
std::queue<int> data_queue;
// 互斥锁，保护共享数据
std::mutex mtx;
// 条件变量，用于线程间通知
std::condition_variable cv;
// 控制程序结束的标志
bool done = false;

// 生产者线程函数
void producer() {
    for (int i = 1; i <= 5; ++i) {
        // 模拟生产数据的耗时操作
        std::this_thread::sleep_for(std::chrono::seconds(1));

        // 加锁保护共享队列
        std::unique_lock<std::mutex> lock(mtx);

        // 生产数据并加入队列
        data_queue.push(i);
        std::cout << "生产者: 生产了数据 " << i << std::endl;

        // 通知消费者有新数据可用
        cv.notify_one();
    }

    // 所有数据生产完毕，设置结束标志并通知消费者
    {
        std::lock_guard<std::mutex> lock(mtx);
        done = true;
    }
    cv.notify_one();
}

// 消费者线程函数
void consumer() {
    while (true) {
        // 加锁保护共享数据
        std::unique_lock<std::mutex> lock(mtx);

        // 等待条件满足：队列不为空或生产结束
        cv.wait(lock, [] {
            return !data_queue.empty() || done;
            });

        // 如果生产结束且队列空，则退出循环
        if (done && data_queue.empty()) {
            break;
        }

        // 处理数据
        int data = data_queue.front();
        data_queue.pop();
        std::cout << "消费者: 处理了数据 " << data << std::endl;
    }

    std::cout << "消费者: 所有数据处理完毕，退出" << std::endl;
}

int main() {
    // 创建生产者和消费者线程
    std::thread prod_thread(producer);
    std::thread cons_thread(consumer);

    // 等待线程完成
    prod_thread.join();
    cons_thread.join();

    return 0;
}
